/**
  ******************************************************************************
  * File Name          : main.c
  * Description        : Main program body
  ******************************************************************************
  *
  * COPYRIGHT(c) 2016 STMicroelectronics
  *
  * Redistribution and use in source and binary forms, with or without modification,
  * are permitted provided that the following conditions are met:
  *   1. Redistributions of source code must retain the above copyright notice,
  *      this list of conditions and the following disclaimer.
  *   2. Redistributions in binary form must reproduce the above copyright notice,
  *      this list of conditions and the following disclaimer in the documentation
  *      and/or other materials provided with the distribution.
  *   3. Neither the name of STMicroelectronics nor the names of its contributors
  *      may be used to endorse or promote products derived from this software
  *      without specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  ******************************************************************************
  */
  /* Includes ------------------------------------------------------------------*/
#include "stm32f1xx_hal.h"
#include "usb_device.h"
#include "usbd_desc.h"

#include "xinput.h"
#include "stm32_xinput.h"
#include "usb_xinput.h"

#include "HCI.h"

//#define DEBUG_UART_HOST 1

#define RX_BUFFER_SIZE 300



/* USER CODE BEGIN Includes */

extern bool pairWiiUsingSync; // True if pairing was done using the Wii SYNC button.
extern bool checkRemoteName; // Used to check remote device's name before connecting.
extern bool incomingPS4; // True if a PS4 controller is connecting
extern  uint8_t classOfDevice[3]; // Class of device of last device


extern uint8_t hci_state; // Current state of Bluetooth HCI connection
extern uint16_t hci_counter; // Counter used for Bluetooth HCI reset loops
extern uint16_t hci_num_reset_loops; // This value indicate how many times it should read before trying to reset
extern uint16_t hci_event_flag; // HCI flags of received Bluetooth events
extern uint8_t inquiry_counter;

#define hci_check_flag(flag) (hci_event_flag & (flag))
#define hci_set_flag(flag) (hci_event_flag |= (flag))
#define hci_clear_flag(flag) (hci_event_flag &= ~(flag))

/** Use this to see if it is waiting for a incoming connection. */
extern bool waitingForConnection;
/** This is used by the service to know when to store the device information. */
extern bool l2capConnectionClaimed;
/** This is used by the SPP library to claim the current SDP incoming request. */
extern bool sdpConnectionClaimed;
/** This is used by the SPP library to claim the current RFCOMM incoming request. */
extern bool rfcommConnectionClaimed;

/** The name you wish to make the dongle show up as. It is set automatically by the SPP library. */
extern const char* btdName;
/** The pin you wish to make the dongle use for authentication. It is set automatically by the SPP and BTHID library. */
extern const char* btdPin;

/** The bluetooth dongles Bluetooth address. */
extern uint8_t my_bdaddr[6];


/** First 30 chars of last remote name. */

/**
 * The supported HCI Version read from the Bluetooth dongle.
 * Used by the PS3BT library to check the HCI Version of the Bluetooth dongle,
 * it should be at least 3 to work properly with the library.
 */
extern uint8_t hci_version;

/** Call this function to pair with a Wiimote */



extern uint8_t hcibuf[300], aclbuf[500];


struct RemoteDevice rd_list[5];

uint8_t tmp_bdaddr[6];
uint8_t tmp_remote_name[6];
uint8_t tmp_handle[2];


/* USER CODE END Includes */

/* Private variables ---------------------------------------------------------*/
//ADC_HandleTypeDef hadc1;
DMA_HandleTypeDef hdma_adc1;
UART_HandleTypeDef huart1;
UART_HandleTypeDef huart2;
DMA_HandleTypeDef hdma_usart1_rx;



/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/

extern USBD_HandleTypeDef* hUsbDevice_0;
uint32_t ADC_buffer[6];

uint8_t _l2CapDataIdentifier;
/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_DMA_Init(void);
static void MX_ADC1_Init(void);

/* USER CODE BEGIN PFP */
/* Private function prototypes -----------------------------------------------*/

/* USER CODE END PFP */
uint8_t USB_RX_Buffer[8] = { 0,0,0,0,0,0,0,0 };
uint8_t USB_TX_Buffer[8] = { 0,0,0,0,0,0,0,0 };

uint8_t hcircvbuftype;
uint8_t hcircvbuf[300];

uint8_t currentNameindex=0;


enum L2CAPMode { Requst, Reponse };

enum L2CAPMode ConnectionMode;


enum ConnectionResponseResult
{
	/// <summary>
	///     Connection successful.
	/// </summary>
	ConnectionSuccessful = 0x0000,

	/// <summary>
	///     Connection pending.
	/// </summary>
	ConnectionPending = 0x0001,

	/// <summary>
	///     Connection refused ?PSM not supported.
	/// </summary>
	ConnectionRefusedPsmNotNupported = 0x0002,

	/// <summary>
	///     Connection refused ?security block.
	/// </summary>
	ConnectionRefusedSecurityBlock = 0x0003,

	/// <summary>
	///     Connection refused ?no resources available.
	/// </summary>
	ConnectionRefusedNoResourcesAvailable = 0x0004
};






struct RemoteDevice* FindByAddress(const uint8_t* addr)
{
	for (int i = 0; i < 4; i++)
	{
		if (addr[0] == rd_list[i].disc_bdaddr[0] && addr[1] == rd_list[i].disc_bdaddr[1]
			&& addr[2] == rd_list[i].disc_bdaddr[2] && addr[3] == rd_list[i].disc_bdaddr[3]
			&& addr[4] == rd_list[i].disc_bdaddr[4] && addr[5] == rd_list[i].disc_bdaddr[5]
			) {
			return &rd_list[i];
		}
	}
	return NULL;

}

struct RemoteDevice* FindByHandle(const uint8_t* Handle)
{
	for (int i = 0; i < 4; i++)
	{
		if (Handle[0] == rd_list[i].hci_handle[0] && Handle[1] == rd_list[i].hci_handle[1]
			) {
			return &rd_list[i];
		}
	}
	return NULL;

}





struct RemoteDevice* FindOrNextEmpty(uint8_t* addr)
{
	for (int i = 0; i < 4; i++)
	{
		if (addr[0] == rd_list[i].disc_bdaddr[0] && addr[1] == rd_list[i].disc_bdaddr[1]
			&& addr[2] == rd_list[i].disc_bdaddr[2] &&addr[3] == rd_list[i].disc_bdaddr[3]
			&& addr[4] == rd_list[i].disc_bdaddr[4] && addr[5] == rd_list[i].disc_bdaddr[5]
			) {
			return &rd_list[i];
		}
	}
	for (int i = 0; i < 4; i++)
	{
		if (0 == rd_list[i].disc_bdaddr[0] && 0 == rd_list[i].disc_bdaddr[1]
			&& 0 == rd_list[i].disc_bdaddr[2] &&0 == rd_list[i].disc_bdaddr[3]
			&&0== rd_list[i].disc_bdaddr[4] && 0 == rd_list[i].disc_bdaddr[5]
			) {
				memcpy(rd_list[i].disc_bdaddr,addr,6);
			return &rd_list[i];
		}
	}
		memset(rd_list[0].disc_bdaddr, 0, 6);
		memset(rd_list[0].disc_linkkey, 0, 16);
		memset(rd_list[0].disc_offset, 0, 2);
		memset(rd_list[0].hci_handle, 0, 2);
		memset(rd_list[0].remote_name, 0, 30);
	

	 memcpy(rd_list[0].disc_bdaddr,addr,6);


	return &rd_list[0];
}
void USART0_Transmit(uint8_t onebyte)
{
	HAL_UART_Transmit(&huart1, &onebyte, 1, HAL_MAX_DELAY);

}
void USART0_TransmitAll(struct QueueFormat* qf)
{
	HAL_UART_Transmit(&huart1,&(qf->commandtype),1,HAL_MAX_DELAY);
	HAL_UART_Transmit(&huart1, qf->data, qf->length, HAL_MAX_DELAY);

}



extern uint8_t USBD_CUSTOM_HID_SendReport(USBD_HandleTypeDef* pdev,
	uint8_t* report,
	uint16_t len);


void MX_USART1_Init(void)
{
	// ENABLE USART1
	__HAL_RCC_USART1_CLK_ENABLE();
	__HAL_RCC_GPIOA_CLK_ENABLE();


	huart1.Instance = USART1;
	huart1.Init.BaudRate = 115200;
	huart1.Init.WordLength = UART_WORDLENGTH_8B;
	huart1.Init.StopBits = UART_STOPBITS_1;
	huart1.Init.Parity = UART_PARITY_NONE;
	huart1.Init.Mode = UART_MODE_TX_RX;
	huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
	huart1.Init.OverSampling = UART_OVERSAMPLING_16;
	if (HAL_UART_Init(&huart1) != HAL_OK)
	{

	}

	__HAL_RCC_USART2_CLK_ENABLE();
	//__HAL_RCC_GPIOB_CLK_ENABLE();



	huart2.Instance = USART2;
	huart2.Init.BaudRate = 115200;
	huart2.Init.WordLength = UART_WORDLENGTH_8B;
	huart2.Init.StopBits = UART_STOPBITS_1;
	huart2.Init.Parity = UART_PARITY_NONE;
	huart2.Init.Mode = UART_MODE_TX_RX;
	huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
	huart2.Init.OverSampling = UART_OVERSAMPLING_16;
	if (HAL_UART_Init(&huart2) != HAL_OK)
	{

	}



	//    hdma_usart1_rx.Instance =  DMA1_Channel3;

	//    hdma_usart1_rx.Init.Direction = DMA_MEMORY_TO_PERIPH;
	//    hdma_usart1_rx.Init.PeriphInc = DMA_PINC_DISABLE;
	//    hdma_usart1_rx.Init.MemInc = DMA_MINC_ENABLE;
	//    hdma_usart1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
	//    hdma_usart1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
	//    hdma_usart1_rx.Init.Mode = DMA_NORMAL;
	//    hdma_usart1_rx.Init.Priority = DMA_PRIORITY_MEDIUM;

	//    HAL_DMA_Init(&hdma_usart1_rx);

	//    __HAL_LINKDMA(&huart1,hdmatx,hdma_usart1_rx);

	 // CONFIG USART INTERUP
	HAL_NVIC_SetPriority(USART1_IRQn, 0, 0);
	HAL_NVIC_EnableIRQ(USART1_IRQn);
	//	
	//		HAL_NVIC_SetPriority(USART3_IRQn, 0, 0);
	//	HAL_NVIC_EnableIRQ(USART3_IRQn);
	//	

  __HAL_UART_ENABLE_IT(&huart1, UART_IT_RXNE);
	//__HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);

}







uint32_t rxConut = 0;


void Flash_WriteData(uint32_t addr,uint16_t *data,uint16_t Size)
{

  HAL_FLASH_Unlock();


    FLASH_EraseInitTypeDef f;
    f.TypeErase = FLASH_TYPEERASE_PAGES;
    f.PageAddress = addr;
    f.NbPages = 1;

    uint32_t PageError = 0;

    HAL_FLASHEx_Erase(&f, &PageError);


	  uint32_t TempBuf = 0;
	  for(uint32_t i = 0;i< Size ;i++)
	 {
		 TempBuf = ~(*(data+i));
		 TempBuf <<= 16;
		 TempBuf += *(data+i); //????
		 HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD , addr + i * 4, TempBuf);
	 }
  

  HAL_FLASH_Lock();
}


uint8_t Flash_ReadData(uint32_t addr,uint16_t *data,uint16_t Size)
{
  uint32_t temp;
	uint8_t result = 1;
  for(uint32_t i = 0;i< Size ;i++)
	{
			temp = *(__IO uint32_t*)(addr + i * 4);
		  if((uint16_t)temp == (uint16_t)(~(temp>>16)))
			{
				*(data+i) = (uint16_t)temp;
			}
			else
			{
				result = 0;
			}
	}
  return result;
}



uint8_t FlashTMPdata[110];

void Rdlist2flash()
{
for(uint8_t i=0;i<5;i++)
	{
	memcpy( (FlashTMPdata+52*i),rd_list[i].disc_bdaddr,6);
	memcpy( (FlashTMPdata+52*i+6),rd_list[i].disc_linkkey,16);	
	memcpy( (FlashTMPdata+52*i+22),rd_list[i].remote_name,30);	
	}
	Flash_WriteData(0X8007d00,(uint16_t*)FlashTMPdata,130);
}
void Flash2Rdlist()
{
Flash_ReadData(0X8007d00,(uint16_t*)FlashTMPdata,130);
	for(uint8_t i=0;i<5;i++)
	{
		memcpy(rd_list[i].disc_bdaddr,(FlashTMPdata+52*i),6);
		memcpy(rd_list[i].disc_linkkey,(FlashTMPdata+52*i+6),16);
		memcpy(rd_list[i].remote_name,(FlashTMPdata+52*i+22),30);
	}
}




void HAL_UART_RxCpltCallback(UART_HandleTypeDef* huart)
{

	if (huart->Instance == USART1)
	{
		if (huart1.RxXferCount == 0)
		{


		}
	}
}







void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
{
	//	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_9 | GPIO_PIN_10 , GPIO_PIN_SET);
	//	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10 | GPIO_PIN_11 , GPIO_PIN_SET);
	GPIO_InitTypeDef GPIO_Initstruct = { 0 };
	if (uartHandle->Instance == USART1)
	{
		__HAL_RCC_USART1_CLK_ENABLE();

		__HAL_RCC_GPIOA_CLK_ENABLE();

		// CONFIG USART1 TX/RX PIN 
		GPIO_Initstruct.Pin = GPIO_PIN_9;
		GPIO_Initstruct.Mode = GPIO_MODE_AF_PP;
		GPIO_Initstruct.Pull = GPIO_NOPULL;
		GPIO_Initstruct.Speed = GPIO_SPEED_FREQ_HIGH;
		//GPIO_Initstruct.Alternate = GPIO_AF7_USART1;
		HAL_GPIO_Init(GPIOA, &GPIO_Initstruct);

		GPIO_Initstruct.Pin = GPIO_PIN_10;
		GPIO_Initstruct.Mode = GPIO_MODE_AF_INPUT;
		GPIO_Initstruct.Pull = GPIO_NOPULL;
		GPIO_Initstruct.Speed = GPIO_SPEED_FREQ_HIGH;
		//GPIO_Initstruct.Alternate = GPIO_AF7_USART1;
		HAL_GPIO_Init(GPIOA, &GPIO_Initstruct);

		__HAL_RCC_USART2_CLK_ENABLE();

		__HAL_RCC_GPIOA_CLK_ENABLE();

		// CONFIG USART1 TX/RX PIN 
		GPIO_Initstruct.Pin = GPIO_PIN_2;
		GPIO_Initstruct.Mode = GPIO_MODE_AF_PP;
		GPIO_Initstruct.Pull = GPIO_NOPULL;
		GPIO_Initstruct.Speed = GPIO_SPEED_FREQ_HIGH;
		//GPIO_Initstruct.Alternate = GPIO_AF7_USART1;
		HAL_GPIO_Init(GPIOA, &GPIO_Initstruct);

		GPIO_Initstruct.Pin = GPIO_PIN_3;
		GPIO_Initstruct.Mode = GPIO_MODE_AF_INPUT;
		GPIO_Initstruct.Pull = GPIO_NOPULL;
		GPIO_Initstruct.Speed = GPIO_SPEED_FREQ_HIGH;
		//GPIO_Initstruct.Alternate = GPIO_AF7_USART1;
		HAL_GPIO_Init(GPIOA, &GPIO_Initstruct);

	}
	//if (uartHandle->Instance == USART3)
	//	{
	//	 GPIO_Initstruct.Pin = GPIO_PIN_10 ;
	//		GPIO_Initstruct.Mode = GPIO_MODE_AF_PP;
	//		GPIO_Initstruct.Pull = GPIO_PULLUP;
	//		GPIO_Initstruct.Speed = GPIO_SPEED_FREQ_LOW;
	//		//GPIO_Initstruct.Alternate = GPIO_AF7_USART1;
	//		HAL_GPIO_Init(GPIOB, &GPIO_Initstruct);

	//		GPIO_Initstruct.Pin = GPIO_PIN_11;
	//		GPIO_Initstruct.Mode = GPIO_MODE_AF_INPUT;
	//		GPIO_Initstruct.Pull = GPIO_NOPULL;
	//		GPIO_Initstruct.Speed = GPIO_SPEED_FREQ_HIGH;
	//		//GPIO_Initstruct.Alternate = GPIO_AF7_USART1;
	//		HAL_GPIO_Init(GPIOB, &GPIO_Initstruct);



	//	}

}



















char tmp[3];




bool DisableSSP = false;

struct RemoteDevice* crd = NULL;

struct RemoteDevice* lstconnect_crd = NULL;

uint16_t mycid = 0x0040;
uint16_t remotecid;
bool HID_ControlConnect=false;
bool HID_InterruptConnect=false;
extern   const char* btdPin ;
uint8_t LinkMode=0;
//uint8_t connectcount=0;

uint32_t tickstart = 0;
bool scanrun=false;

void HCI_event_task() {
	switch (hcircvbuf[0]) { // Switch on event type
	case EV_COMMAND_COMPLETE:
		if (true){//(!hcircvbuf[5]) { // Check if command succeeded

			hci_set_flag(HCI_FLAG_CMD_COMPLETE); // Set command complete flag

			if ((hcircvbuf[3] == 0x03) && (hcircvbuf[4] == 0x0C)) {//HCI_Reset
				ConnectionMode = Reponse;
				hci_read_bdaddr();
				
			}
			else if ((hcircvbuf[3] == 0x09) && (hcircvbuf[4] == 0x10)) { //HCI_Read_BD_ADDR  Parameters from read local bluetooth address
				for (uint8_t i = 0; i < 6; i++)
					my_bdaddr[i] = hcircvbuf[6 + i];
				hci_set_flag(HCI_FLAG_READ_BDADDR);
				hci_read_buffer_size();
			}
			else if ((hcircvbuf[3] == 0x05) && (hcircvbuf[4] == 0x10)) {//HCI_Read_Buffer_Size
				hci_read_local_version_information();

			}
			else if ((hcircvbuf[3] == 0x01) && (hcircvbuf[4] == 0x10)) { // Parameters from read local version information
				hci_version = hcircvbuf[6]; // Used to check if it supports 2.0+EDR - see http://www.bluetooth.org/Technical/AssignedNumbers/hci.htm
				hci_set_flag(HCI_FLAG_READ_VERSION);
				if (DisableSSP)
				{
					hci_write_authentication_enable();
				}
				else
				{
					//hci_write_authentication_enable();
					hci_write_simple_paring_mode();

				}


			}
			else if ((hcircvbuf[3] == 0x1a) && (hcircvbuf[4] == 0x0c))//hci_write_scan_enable
			{

       //hci_inquiry();
				scanrun=true;
			
				
				break;
				

			}
			else if ((hcircvbuf[3] == 0x56) && (hcircvbuf[4] == 0x0c))//hci_write_simple_paring_mode
			{
				if (hcircvbuf[5] == 0)
				{
					hci_write_simple_paring_debug_mode();

				}
				else
				{
					DisableSSP = true;
					hci_write_scan_enable();
				}
			}

			else if ((hcircvbuf[3] == 0x04) && (hcircvbuf[4] == 0x18))//HCI_Write_Simple_Pairing_Debug_Mode
			{
				hci_write_authentication_enable();
			}

			else if ((hcircvbuf[3] == 0x20) && (hcircvbuf[4] == 0x0c))//HCI_Write_Authentication_Enable
			{
				if (hcircvbuf[5] == 0)
				{
					hci_set_event_mask();
				}
				else
				{
					DisableSSP = true;
					hci_write_scan_enable();
				}
			}
			else if ((hcircvbuf[3] == 0x01) && (hcircvbuf[4] == 0x0c))//HCI_Set_Event_Mask
			{

				if (hcircvbuf[5] == 0)
				{
					hci_write_page_timeout();
				}
				else
				{
					DisableSSP = true;

					hci_write_scan_enable();
				}
			}
			else if ((hcircvbuf[3] == 0x18) && (hcircvbuf[4] == 0x0c) && hcircvbuf[5] == 0)//HCI_Write_Page_Timeout
			{
				hci_write_page_scan_activity();
			}
			else if ((hcircvbuf[3] == 0x1c) && (hcircvbuf[4] == 0x0c) && hcircvbuf[5] == 0)//HCI_Write_Page_Scan_Activity
			{
				hci_write_page_scan_type();
			}
			else if ((hcircvbuf[3] == 0x47) && (hcircvbuf[4] == 0x0c) && hcircvbuf[5] == 0)//HCI_Write_Page_Scan_Type
			{
				hci_write_inquiry_scan_activity();
			}
			else if ((hcircvbuf[3] == 0x1e) && (hcircvbuf[4] == 0x0c) && hcircvbuf[5] == 0)//HCI_Write_Inquiry_Scan_Activity
			{
				hci_write_inquiry_scan_type();
			}
			else if ((hcircvbuf[3] == 0x43) && (hcircvbuf[4] == 0x0c) && hcircvbuf[5] == 0)//HCI_Write_Inquiry_Scan_Activity
			{
				hci_write_inquiry_mode();
			}
			else if ((hcircvbuf[3] == 0x45) && (hcircvbuf[4] == 0x0c) && hcircvbuf[5] == 0)//HCI_Write_Inquiry_Scan_Activity
			{
				hci_write_class_of_device();
			}
			else if ((hcircvbuf[3] == 0x24) && (hcircvbuf[4] == 0x0c) && hcircvbuf[5] == 0)//HCI_Write_Inquiry_Scan_Activity
			{
				hci_write_extended_inquiry_response();
			}
			else if ((hcircvbuf[3] == 0x52) && (hcircvbuf[4] == 0x0c) && hcircvbuf[5] == 0)//HCI_Write_Inquiry_Scan_Activity
			{
				hci_write_local_name();
			}
			else if ((hcircvbuf[3] == 0x13) && (hcircvbuf[4] == 0x0c) && hcircvbuf[5] == 0)//HCI_Write_Inquiry_Scan_Activity
			{
				 hci_write_scan_enable();
			}
			else if ((hcircvbuf[3] == 0x0d) && (hcircvbuf[4] == 0x08) )//Write Link Policy Settings
			{
				tmp_handle[0] = hcircvbuf[6];
	      tmp_handle[1] = hcircvbuf[7];

  	crd = 	FindByHandle(tmp_handle);
	if (crd == NULL){break;}

	 hci_write_link_timeout	(crd);
			}
			else if ((hcircvbuf[3] == 0x37) && (hcircvbuf[4] == 0x0c) )//Write Link Policy Settings
			{
				tmp_handle[0] = hcircvbuf[6];
	      tmp_handle[1] = hcircvbuf[7];

	crd = 	FindByHandle(tmp_handle);
	if (crd == NULL){break;}
	     hci_authentication_request(crd);
       //hci_remote_name(crd);
			}
		}// command return success
		break;

	case EV_COMMAND_STATUS:
		if (hcircvbuf[2]) { // Show status on serial if not OK
#ifdef DEBUG_UART_HOST
			Notify(PSTR("\r\nHCI Command Failed: "), 0x80);
			D_PrintHex(hcircvbuf[2], 0x80);
#endif
		}
		if ((hcircvbuf[4] == 0x0C) && (hcircvbuf[5] == 0x01))//HCI_Set_Event_Mask
		{
			if (hcircvbuf[2] != 0)
			{
				DisableSSP = true;
				hci_write_scan_enable();
			}
		}
		else if ((hcircvbuf[4] == 0x0c) && (hcircvbuf[5] == 0x04))//Link Key Negative
		{

		}
		else if ((hcircvbuf[4] == 0x05) && (hcircvbuf[5] == 0x04))//create connection
		{

		}
		else if ((hcircvbuf[4] == 0x04) && (hcircvbuf[5] == 0x01))//HCI_Inquiry
		{

		}
		break;



	case EV_INQUIRY_COMPLETE:


		hci_remote_name(&rd_list[currentNameindex]);
	
	
	
	 
	
	

		inquiry_counter++;
		break;

	case EV_INQUIRY_RESULT:
		if (hcircvbuf[2]) { // Check that there is more than zero responses
#ifdef EXTRADEBUG
			Notify(PSTR("\r\nNumber of responses: "), 0x80);
			D_PrintHex(hcircvbuf[2], 0x80);
#endif
			for (uint8_t i = 0; i < hcircvbuf[2]; i++) {

				tmp_bdaddr[0] = hcircvbuf[3 + 14 * i];
				tmp_bdaddr[1] = hcircvbuf[4 + 14 * i];
				tmp_bdaddr[2] = hcircvbuf[5 + 14 * i];
				tmp_bdaddr[3] = hcircvbuf[6 + 14 * i];
				tmp_bdaddr[4] = hcircvbuf[7 + 14 * i];
				tmp_bdaddr[5] = hcircvbuf[8 + 14 * i];

				classOfDevice[0] = hcircvbuf[11 + 14 * i];
				classOfDevice[2] = hcircvbuf[12 + 14 * i];
				classOfDevice[2] = hcircvbuf[13 + 14 * i];

				crd = FindOrNextEmpty(tmp_bdaddr);
				if (crd == NULL) { break; }
				for (uint8_t j = 0; j < 6; j++)
				{
					crd->disc_bdaddr[j] = tmp_bdaddr[j];
				}


				crd->disc_offset[0] = hcircvbuf[14];
				crd->disc_offset[1] = hcircvbuf[15];

				crd->state = 'I';

				hci_set_flag(HCI_FLAG_DEVICE_FOUND);

	
				

			}//

		}
		break;

	case EV_HCI_Inquiry_Result_With_RSSI:
		if (hcircvbuf[2]) { // Check that there is more than zero responses
#ifdef EXTRADEBUG
			Notify(PSTR("\r\nNumber of responses: "), 0x80);
			D_PrintHex(hcircvbuf[2], 0x80);
#endif
			for (uint8_t i = 0; i < hcircvbuf[2]; i++) {
				uint8_t offset = 8 * hcircvbuf[2] + 3 * i;

				for (uint8_t j = 0; j < 3; j++)
					classOfDevice[j] = hcircvbuf[j + 4 + offset];

#ifdef EXTRADEBUG
				Notify(PSTR("\r\nClass of device: "), 0x80);
				D_PrintHex(classOfDevice[2], 0x80);
				Notify(PSTR(" "), 0x80);
				D_PrintHex(classOfDevice[1], 0x80);
				Notify(PSTR(" "), 0x80);
				D_PrintHex(classOfDevice[0], 0x80);
#endif

				
				tmp_bdaddr[0] = hcircvbuf[3 + 14 * i];
				tmp_bdaddr[1] = hcircvbuf[4 + 14 * i];
				tmp_bdaddr[2] = hcircvbuf[5 + 14 * i];
				tmp_bdaddr[3] = hcircvbuf[6 + 14 * i];
				tmp_bdaddr[4] = hcircvbuf[7 + 14 * i];
				tmp_bdaddr[5] = hcircvbuf[8 + 14 * i];
       crd = FindOrNextEmpty(tmp_bdaddr);
				if (crd == NULL) { break; }
				classOfDevice[0] = hcircvbuf[11 + 14 * i];
				classOfDevice[2] = hcircvbuf[12 + 14 * i];
				classOfDevice[2] = hcircvbuf[13 + 14 * i];

				
				for (uint8_t j = 0; j < 6; j++)
				{
					crd->disc_bdaddr[j] = tmp_bdaddr[j];
				}


				crd->disc_offset[0] = hcircvbuf[14];
				crd->disc_offset[1] = hcircvbuf[15];
				hci_set_flag(HCI_FLAG_DEVICE_FOUND);


			}//EVERY DEVICEREPEAT
	}
		break;

	case EV_REMOTE_NAME_COMPLETE:
		if (!hcircvbuf[2]) { // Check if reading is OK

			tmp_bdaddr[0] = hcircvbuf[3];
			tmp_bdaddr[1] = hcircvbuf[4];
			tmp_bdaddr[2] = hcircvbuf[5];
			tmp_bdaddr[3] = hcircvbuf[6];
			tmp_bdaddr[4] = hcircvbuf[7];
			tmp_bdaddr[5] = hcircvbuf[8];

			crd = FindByAddress(tmp_bdaddr);
			if (crd == NULL) { break; }

			for (uint8_t i = 0; i < min(sizeof(crd->remote_name), sizeof(hcircvbuf) - 9); i++) {
				crd->remote_name[i] = hcircvbuf[9 + i];
				if (crd->remote_name[i] == '\0') // End of string
					break;
			}
			// TODO: Altid s? '\0' i remote name!
			hci_set_flag(HCI_FLAG_REMOTE_NAME_COMPLETE);

		}
		if (strstr(crd->remote_name, "Fuze") != NULL) {
			btdPin="0000";
			if (crd->state == 'I')
			{
				hci_connect(crd);
					crd->state ='N';
			}
			else if (crd->state == 'C')
			{
				
				hci_authentication_request(crd);
					crd->state ='N';
			}
      LinkMode=1;
			break;
		}
		else if (strstr(crd->remote_name, "Ngame") != NULL) {
			 btdPin="1234";
			if (crd->state == 'I')
			{
				hci_connect(crd);
			  crd->state ='N';
			}
			else if (crd->state == 'C')
			{
				
				hci_authentication_request(crd);
				crd->state ='N';
			}
			LinkMode=2;
			break;
		}
		else if (currentNameindex<=5) {
			currentNameindex++;
			hci_remote_name(&rd_list[currentNameindex]);
		}


		break;
	case EV_CONNECT_COMPLETE: //HCI_Connection_Complete_EV
		hci_set_flag(HCI_FLAG_CONNECT_EVENT);
		if (!hcircvbuf[2]) { // Check if connected OK
#ifdef EXTRADEBUG
			Notify(PSTR("\r\nConnection established"), 0x80);
#endif


			tmp_bdaddr[0] = hcircvbuf[5];
			tmp_bdaddr[1] = hcircvbuf[6];
			tmp_bdaddr[2] = hcircvbuf[7];
			tmp_bdaddr[3] = hcircvbuf[8];
			tmp_bdaddr[4] = hcircvbuf[9];
			tmp_bdaddr[5] = hcircvbuf[10];

			crd = FindByAddress(tmp_bdaddr);
			if (crd == NULL) { break; }
			crd->hci_handle[0] = hcircvbuf[3];
			crd->hci_handle[1] = hcircvbuf[4];
			crd->state = 'C';

			// Store the handle for the ACL connection
			hci_set_flag(HCI_FLAG_CONNECT_COMPLETE); // Set connection complete flag

		

		}
		else {
			hci_state = HCI_CHECK_DEVICE_SERVICE;
#ifdef DEBUG_UART_HOST
			Notify(PSTR("\r\nConnection Failed: "), 0x80);
			D_PrintHex(hcircvbuf[2], 0x80);
#endif
//			connectcount++;
//			NextConnect:
//			 if(rd_list[connectcount].disc_linkkey[0]>0)
//				{
//			hci_connect(&rd_list[connectcount]);
//					break;
//			}
//				else{
//					connectcount++;
//					if (connectcount>4)
//			{
//			hci_inquiry();
//				break;
//			}
//			goto	NextConnect;
//		      
//				}
				
		}
		break;

	case EV_DISCONNECT_COMPLETE:
		if (!hcircvbuf[2]) { // Check if disconnected OK
			hci_set_flag(HCI_FLAG_DISCONNECT_COMPLETE); // Set disconnect command complete flag
			hci_clear_flag(HCI_FLAG_CONNECT_COMPLETE); // Clear connection complete flag
		}

		break;



	case EV_INCOMING_CONNECT: //HCI_Connection_Request_EV
		for (uint8_t i = 0; i < 6; i++)
			tmp_bdaddr[i] = hcircvbuf[i + 2];

		for (uint8_t i = 0; i < 3; i++)
			classOfDevice[i] = hcircvbuf[i + 8];




		//		if ((classOfDevice[1] & 0x05) && (classOfDevice[0] & 0xC8)) { // Check if it is a mouse, keyboard or a gamepad
		//#ifdef DEBUG_UART_HOST
		//			if (classOfDevice[0] & 0x80)
		//				Notify(PSTR("\r\nMouse is connecting"), 0x80);
		//			if (classOfDevice[0] & 0x40)
		//				Notify(PSTR("\r\nKeyboard is connecting"), 0x80);
		//			if (classOfDevice[0] & 0x08)
		//				Notify(PSTR("\r\nGamepad is connecting"), 0x80);
		//#endif
		//			incomingHIDDevice = true;	
		//			//hci_delete_stored_link_key();
		//	
		//		}

		//#ifdef EXTRADEBUG
		//		Notify(PSTR("\r\nClass of device: "), 0x80);
		//		D_PrintHex(classOfDevice[2], 0x80);
		//		Notify(PSTR(" "), 0x80);
		//		D_PrintHex(classOfDevice[1], 0x80);
		//		Notify(PSTR(" "), 0x80);
		//		D_PrintHex(classOfDevice[0], 0x80);
		//#endif
		hci_set_flag(HCI_FLAG_INCOMING_REQUEST);    //hci_set_flag(HCI_FLAG_INCOMING_REQUEST);
		hci_state = HCI_CONNECT_IN_STATE;

		crd = FindByAddress(tmp_bdaddr);


		if (strstr(crd->remote_name, "Fuze") != NULL )
		{
			hci_delete_stored_link_key(crd);
			//WaitRX();
			hci_accept_connection(crd);
			//WaitRX();
			//hci_remote_name(crd);
			//hci_authentication_request(crd);
			 LinkMode=1;
		}
		else	if ( strstr(crd->remote_name, "Ngame") != NULL)
		{
			hci_delete_stored_link_key(crd);
			//WaitRX();
			hci_accept_connection(crd);
			//WaitRX();
			//hci_remote_name(crd);
			//hci_authentication_request(crd);
			 LinkMode=2;
		}
		//ConnectionMode = Requst;



		break;

	case EV_PIN_CODE_REQUEST:

		tmp_bdaddr[0] = hcircvbuf[2];
		tmp_bdaddr[1] = hcircvbuf[3];
		tmp_bdaddr[2] = hcircvbuf[4];
		tmp_bdaddr[3] = hcircvbuf[5];
		tmp_bdaddr[4] = hcircvbuf[6];
		tmp_bdaddr[5] = hcircvbuf[7];

		crd = FindByAddress(tmp_bdaddr);
		if (crd == NULL) { break; }

		if (btdPin != NULL) {
#ifdef DEBUG_UART_HOST
			Notify(PSTR("\r\nBluetooth pin is set too: "), 0x80);
			Notify(btdPin, 0x80);
#endif
			hci_pin_code_request_reply(crd);
		}
		else {
#ifdef DEBUG_UART_HOST
			Notify(PSTR("\r\nNo pin was set"), 0x80);
#endif
			hci_pin_code_negative_request_reply(crd);
		}
		break;

	case EV_IO_Capability_Request:
		tmp_bdaddr[0] = hcircvbuf[2];
		tmp_bdaddr[1] = hcircvbuf[3];
		tmp_bdaddr[2] = hcircvbuf[4];
		tmp_bdaddr[3] = hcircvbuf[5];
		tmp_bdaddr[4] = hcircvbuf[6];
		tmp_bdaddr[5] = hcircvbuf[7];

		crd = FindByAddress(tmp_bdaddr);
		if (crd == NULL) { break; }
		hci_io_capability_request_reply(crd);
		break;
	case EV_User_Confirmation_Request:
		tmp_bdaddr[0] = hcircvbuf[2];
		tmp_bdaddr[1] = hcircvbuf[3];
		tmp_bdaddr[2] = hcircvbuf[4];
		tmp_bdaddr[3] = hcircvbuf[5];
		tmp_bdaddr[4] = hcircvbuf[6];
		tmp_bdaddr[5] = hcircvbuf[7];

		crd = FindByAddress(tmp_bdaddr);
		if (crd == NULL) { break; }
		HAL_Delay(2000);
		hci_user_confirmation_request_reply(crd);
		break;

	case EV_LINK_KEY_REQUEST:
#ifdef DEBUG_UART_HOST
		Notify(PSTR("\r\nReceived Key Request"), 0x80);
#endif
		tmp_bdaddr[0] = hcircvbuf[2];
		tmp_bdaddr[1] = hcircvbuf[3];
		tmp_bdaddr[2] = hcircvbuf[4];
		tmp_bdaddr[3] = hcircvbuf[5];
		tmp_bdaddr[4] = hcircvbuf[6];
		tmp_bdaddr[5] = hcircvbuf[7];

					 crd= 	FindByAddress(tmp_bdaddr);
			


		if (crd == NULL) { break; }
crd->state='L';
		if (crd->disc_linkkey[0] == 0)
		{
			
			hci_link_key_request_negative_reply(crd);

		}
		else
		{
			hci_link_key_request_reply(crd);
		}
		break;
	case EV_LINK_KEY_NOTIFICATION:
#ifdef DEBUG_UART_HOST
		Notify(PSTR("\r\nLink key notification event"), 0x80);
#endif

		tmp_bdaddr[0] = hcircvbuf[2];
		tmp_bdaddr[1] = hcircvbuf[3];
		tmp_bdaddr[2] = hcircvbuf[4];
		tmp_bdaddr[3] = hcircvbuf[5];
		tmp_bdaddr[4] = hcircvbuf[6];
		tmp_bdaddr[5] = hcircvbuf[7];

		crd = FindByAddress(tmp_bdaddr);
		if (crd == NULL) { break; }

		for (uint8_t i = 0; i < 16; i++)
			{
				crd->disc_linkkey[i] = hcircvbuf[i + 8];
			}
		Rdlist2flash();
		break;
		
		
		
	case EV_AUTHENTICATION_COMPLETE:

		tmp_handle[0] = hcircvbuf[3];
		tmp_handle[1] = hcircvbuf[4];
		crd = FindByHandle(tmp_handle);
		if (crd == NULL) { break; }
		if (!hcircvbuf[2]) { // Check if pairing was successful

#ifdef DEBUG_UART_HOST
			Notify(PSTR("\r\nPairing successful with HID device"), 0x80);
#endif




			_l2CapDataIdentifier++;
			l2cap_connection_request(crd, _l2CapDataIdentifier++, (uint8_t*)&mycid,
				HID_CTRL_PSM);
			HID_ControlConnect=true;


		}
		else {
#ifdef DEBUG_UART_HOST
			Notify(PSTR("\r\nPairing Failed: "), 0x80);
			D_PrintHex(hcircvbuf[2], 0x80);
#endif
			//hci_authentication_request(crd);
			memset(crd->disc_linkkey,0,16);
				Rdlist2flash();
			//hci_authentication_request(crd);
		}





		break;
		
		case EV_Simple_Pairing_Complete:
		if (hcircvbuf[2] >0) {
		#ifdef usart2_log
		HAL_UART_Transmit(&huart2,(uint8_t*)"SIMPLE PAIR FAIL",16,2000);
		#endif	
		}
		break;
		/* We will just ignore the following events */
	case EV_NUM_COMPLETE_PKT:
#ifdef DEBUG_UART_HOST
		Notify(PSTR("\r\nNum Complete Packet"), 0x80);
#endif
		break;

	case EV_ROLE_CHANGED:
#ifdef DEBUG_UART_HOST
		Notify(PSTR("\r\nRole Changed"), 0x80);
#endif
		break;

	case EV_PAGE_SCAN_REP_MODE:
		if (HCI_FLAG_PSCAN_REP) {
			hci_set_flag(HCI_FLAG_PSCAN_REP);
		}
		break;

	case EV_LOOPBACK_COMMAND:
#ifdef DEBUG_UART_HOST
		Notify(PSTR("\r\nLoopBack Command"), 0x80);
#endif
		break;
	case EV_DATA_BUFFER_OVERFLOW:
#ifdef DEBUG_UART_HOST
		Notify(PSTR("\r\nData Buffer Overflow Event"), 0x80);
#endif
		break;
	case EV_CHANGE_CONNECTION_LINK:
#ifdef DEBUG_UART_HOST
		Notify(PSTR("\r\nChange Connection Link Event"), 0x80);
#endif
		break;
	case EV_MAX_SLOTS_CHANGE:
#ifdef DEBUG_UART_HOST
		Notify(PSTR("\r\nMax slots changed event"), 0x80);
#endif
	tmp_handle[0] = hcircvbuf[2];
	tmp_handle[1] = hcircvbuf[3];

	crd = 	FindByHandle(tmp_handle);
	if (crd == NULL){break;}
		hci_write_link_policy(crd);
   
		break;
	case EV_QOS_SETUP_COMPLETE:
#ifdef DEBUG_UART_HOST
		Notify(PSTR("\r\nQOS Setup Complete Event"), 0x80);
#endif
		break;

	case EV_ENCRYPTION_CHANGE:
#ifdef DEBUG_UART_HOST
		Notify(PSTR("\r\nEncryption Change Event"), 0x80);
#endif
		break;
	case EV_READ_REMOTE_VERSION_INFORMATION_COMPLETE:
		if (!hcircvbuf[2]) {
#ifdef DEBUG_UART_HOST
			Notify(PSTR("\r\nRead remote version complete"), 0x80);
#endif
			hci_set_flag(HCI_FLAG_REMOTE_VER_COMPLETE);
}
		else {
#ifdef DEBUG_UART_HOST
			Notify(PSTR("\r\nRead remote version failed"), 0x80);
#endif
		}
		break;
	case EV_CHANGE_PACKET_TYPE_COMPLETE:
		if (!hcircvbuf[2]) {
			hci_set_flag(HCI_FLAG_CHANGE_PTYPE_COMPLETE);
#ifdef DEBUG_UART_HOST
			Notify(PSTR("\r\nChange Packet type successful"), 0x80);
#endif
		}
		else {
#ifdef DEBUG_UART_HOST
			Notify(PSTR("\r\nChange Packet type failed"), 0x80);
#endif
		}
	default:
#ifdef EXTRADEBUG
	default:
		if (hcircvbuf[0] != 0x00) {
			Notify(PSTR("\r\nUnmanaged HCI Event: "), 0x80);
			D_PrintHex(hcircvbuf[0], 0x80);
		}

		break;
#endif

		break;
		} // Switch

		}










uint8_t ResponseIndex = 1;


uint8_t control_remotecid[2]={0x40,0x00};
uint8_t interrupt_remotecid[2]={0x41,0x00};
uint8_t control_mycid[2]={0x40,0x00};
uint8_t interrupt_mycid[2]={0x41,0x00};
uint8_t identifier = 0;


/* L2CAP Channels */



/* marktype 1byte
   handle 2byte
	 acllength 2byte
	 l2caplength 2byte
	 channel 2byte(fix 01 00)
	 event 1byte
	 eventid 1byte
	 eventlength 2byte
	 descid 2byte
	 scid 2byte
*/

bool isbittrue(uint8_t testvalue, uint8_t pos)
{
    return  ((1 << (pos-1)) & testvalue)>>(pos-1);

}
uint8_t setbit(uint8_t input, uint8_t pos, bool bitvalue)
{
    //when true with  1000 or caculate
    //when false with 0111 and caculate
    if (bitvalue==true)
    {
        return   (1 << (pos - 1)) | input;
    }
    else
    {
        return  (~(1 << (pos - 1))) &input;
    }

}

uint16_t CommandIndex=0;
bool IdleStarted=false;
uint8_t FuzeResponse[]={0xa2,0x04,0x00,0x00,0x40,0x00,0x00 };

void FuzeUSB()
{
	 /*
            None = 0,

            XboxData[2],XBOXDATA 
            Up = 1 << 0,
            Down = 1 << 1,
            Left = 1 << 2,
            Right = 1 << 3,
            Start = 1 << 4,
	
            Back = 1 << 5,
            L3 = 1 << 6,
            R3 = 1 << 7,

           
	*/
	
	 uint8_t inpad=(*(hcircvbuf+12))& (~0xF0);
	
//		sprintf(tmp,"%02x,",inpad);
//	 HAL_UART_Transmit(&huart2,(uint8_t*)"\rPAD",4,500);
//		HAL_UART_Transmit(&huart2,(uint8_t*)tmp,3,500);
		
	 uint8_t pads = 0;
	 switch (inpad) {
                         case 0:
                            pads = setbit(pads,1,true);
                        break;
                          case 1:
                             pads = setbit(pads,1,true);
                             pads = setbit(pads,4,true);
                        break;
                          case 2:
                            pads = setbit(pads,4,true);
                        break;
                          case 3:
                              pads = setbit(pads,2,true);
                              pads = setbit(pads,4,true);
                        break;
                          case 4:
                            pads = setbit(pads,2,true);
                        break;
                          case 5:
                              pads = setbit(pads,2,true);
                              pads = setbit(pads,3,true);
                        break;
                          case 6:
                           pads = setbit(pads,3,true);
                        break;
                          case 7:
                          pads = setbit(pads,1,true);
                              pads = setbit(pads,3,true);
                        break;
                    default:
                        break;
                }
	      pads = setbit(pads,5,isbittrue(*(hcircvbuf+11),3));
				pads = setbit(pads,6,isbittrue(*(hcircvbuf+11),4));
				pads = setbit(pads,7,isbittrue(*(hcircvbuf+11),6));
				pads = setbit(pads,8,isbittrue(*(hcircvbuf+11),7));
	  *(TXData + 2)= pads;
	/*
						LB = 1 << 8([3] byte),
            RB = 1 << 9,
            Guide = 1 << 10,

            A = 1 << 12,
            B = 1 << 13,
            X = 1 << 14,
            Y = 1 << 15
								*/
								uint8_t btons = 0;          
								btons = setbit(btons,1,isbittrue(*(hcircvbuf+10),7));
                btons = setbit(btons,2,isbittrue(*(hcircvbuf+10),8));
								
                btons = setbit(btons,5,isbittrue(*(hcircvbuf+10),1));
                btons = setbit(btons,6,isbittrue(*(hcircvbuf+10),2));
                btons = setbit(btons,7,isbittrue(*(hcircvbuf+10),4));
                btons = setbit(btons,8,isbittrue(*(hcircvbuf+10),5));
     
                *(TXData + 3)=btons;//??????12??
								/*
                      ([4]byte),
                      L2(???)
                      ([5]byte),
                      R2(???)
                      [6]byte,   left  axis X+
                      [7]byte,   left  axis Y+
											[8]byte left axis X-
											[9]byte left axis Y-
											
											[10]byte,   RIGHT  axis X+
                      [11]byte,   RIGHT  axis Y+
											[12]byte RIGHT axis X-
											[13]byte RIGHT axis Y-
                      
                 */
						   memcpy(TXData + 4, (hcircvbuf) + 17, 1);
						   memcpy(TXData + 5, (hcircvbuf) + 18, 1);
		
	             	*(TXData + 6)= *(hcircvbuf+13) -128;//??????12??
                *(TXData + 7)= *(hcircvbuf+13) -128;//??????12??
                *(TXData + 8)= -(*(hcircvbuf+14)-127) ;//??????12??
                *(TXData + 9)= -(*(hcircvbuf+14)-127) ;//??????12??

                //???
                *(TXData + 10)= *(hcircvbuf+15) -128;//??????12??
                *(TXData + 11)= *(hcircvbuf+15) -128;//??????12??
                *(TXData + 12)= -*((hcircvbuf+16)-127) ;//??????12??
                *(TXData + 13)= -(*(hcircvbuf+16)-127) ;//??????12??
		
		
		USBD_CUSTOM_HID_SendReport(hUsbDevice_0, TXData, XINPUT_TX_SIZE);
		//L2CAP_Command(crd,FuzeResponse,7,interrupt_remotecid[0],interrupt_remotecid[1] );
}
void NgameUSB()
{
	 /*
            None = 0,

            XboxData[2],XBOXDATA 
            Up = 1 << 0,
            Down = 1 << 1,
            Left = 1 << 2,
            Right = 1 << 3,
            Start = 1 << 4,
	
            Back = 1 << 5,
            L3 = 1 << 6,
            R3 = 1 << 7,

           
	*/
	
	 uint8_t inpad=*(hcircvbuf+14);
	 uint8_t pads = 0;
	 switch (inpad) {
                        case 0:
                            pads = setbit(pads,1,true);
                        break;
                          case 1:
                             pads = setbit(pads,1,true);
                             pads = setbit(pads,4,true);
                        break;
                          case 2:
                            pads = setbit(pads,4,true);
                        break;
                          case 3:
                              pads = setbit(pads,2,true);
                              pads = setbit(pads,4,true);
                        break;
                          case 4:
                            pads = setbit(pads,2,true);
                        break;
                          case 5:
                              pads = setbit(pads,2,true);
                              pads = setbit(pads,3,true);
                        break;
                          case 6:
                           pads = setbit(pads,3,true);
                        break;
                          case 7:
                          pads = setbit(pads,1,true);
                              pads = setbit(pads,3,true);
                        break;
                    default:
                        break;
                }
	      pads = setbit(pads,5,isbittrue(*(hcircvbuf+16),4));
				if (hcircvbuf[9]==0x03)
				{
				if (hcircvbuf[11]==0x24)
				{
					pads = setbit(pads,6,1);
				}
				}					
				
								
				pads = setbit(pads,7,isbittrue(*(hcircvbuf+16),6));
				pads = setbit(pads,8,isbittrue(*(hcircvbuf+16),7));
	  *(TXData + 2)= pads;
	/*
						LB = 1 << 8([3] byte),
            RB = 1 << 9,
            Guide = 1 << 10,

            A = 1 << 12,
            B = 1 << 13,
            X = 1 << 14,
            Y = 1 << 15
								*/
								uint8_t btons = 0;
								btons = setbit(btons,1,isbittrue(*(hcircvbuf+15),7));
                btons = setbit(btons,2,isbittrue(*(hcircvbuf+15),8));
								
                btons = setbit(btons,5,isbittrue(*(hcircvbuf+15),1));
                btons = setbit(btons,6,isbittrue(*(hcircvbuf+15),2));
                btons = setbit(btons,7,isbittrue(*(hcircvbuf+15),4));
                btons = setbit(btons,8,isbittrue(*(hcircvbuf+15),5));
               
                *(TXData + 3)=btons;//??????12??
								/*
                      ([4]byte),
                      L2(???)
                      ([5]byte),
                      R2(???)
                      [6]byte,   left  axis X+
                      [7]byte,   left  axis Y+
											[8]byte left axis X-
											[9]byte left axis Y-
											
											[10]byte,   RIGHT  axis X+
                      [11]byte,   RIGHT  axis Y+
											[12]byte RIGHT axis X-
											[13]byte RIGHT axis Y-
                      
                 */
								 memcpy(TXData + 4, (hcircvbuf) + 18, 1);
								 memcpy(TXData + 5, (hcircvbuf) + 17, 1);
								
	             	*(TXData + 6)= *(hcircvbuf+10) -128;//??????12??
                *(TXData + 7)= *(hcircvbuf+10) -128;//??????12??
                *(TXData + 8)= -(*(hcircvbuf+11)-127) ;//??????12??
                *(TXData + 9)= -(*(hcircvbuf+11)-127) ;//??????12??

                //???
                *(TXData + 10)= *(hcircvbuf+12) -128;//??????12??
                *(TXData + 11)= *(hcircvbuf+12) -128;//??????12??
                *(TXData + 12)= -*((hcircvbuf+13)-127) ;//??????12??
                *(TXData + 13)= -(*(hcircvbuf+13)-127) ;//??????12??
		
		
		USBD_CUSTOM_HID_SendReport(hUsbDevice_0, TXData, XINPUT_TX_SIZE);
		//L2CAP_Command(crd,FuzeResponse,7,interrupt_remotecid[0],interrupt_remotecid[1] );
}



void ACL_event_task()
{



	tmp_handle[0] = hcircvbuf[0];
	tmp_handle[1] = hcircvbuf[1] & 0x0f;

	crd =  	FindByHandle(tmp_handle);
	if (crd == NULL) { return; }

	if (hcircvbuf[6] == 0x01 && hcircvbuf[7] == 0x00) // Control Channel
	{
		switch (hcircvbuf[8])
		{
		case L2CAP_CMD_COMMAND_REJECT:

			break;

		case L2CAP_CMD_CONNECTION_REQUEST:

		ConnectionMode =Requst;

			if ((hcircvbuf[12] | (hcircvbuf[13] << 8)) == HID_CTRL_PSM) {
				identifier = hcircvbuf[9];
				control_remotecid[0] = hcircvbuf[14];
				control_remotecid[1] = hcircvbuf[15];
				mycid = control_remotecid[0]|( control_remotecid[1]<<8) ;
      	control_mycid[0] = hcircvbuf[14];
				control_mycid[1] = hcircvbuf[15];
        HID_ControlConnect=true;
			}
			else if ((hcircvbuf[12] | (hcircvbuf[13] << 8)) == HID_INTR_PSM) {
				identifier = hcircvbuf[9];
				interrupt_remotecid[0] = hcircvbuf[14];
				interrupt_remotecid[1] = hcircvbuf[15];
				mycid = interrupt_remotecid[0]|( interrupt_remotecid[1]<<8) ;
				interrupt_mycid[0] = hcircvbuf[14];
				interrupt_mycid[1] = hcircvbuf[15];
        HID_InterruptConnect=true;
			}


			// send response with connection successful

			remotecid=hcircvbuf[14]|(hcircvbuf[15]<<8);
		
			

			l2cap_connection_response(crd,
				hcircvbuf[9], (uint8_t*)&mycid, (uint8_t*)&remotecid,
				ConnectionSuccessful);

			l2cap_config_request(crd, _l2CapDataIdentifier++, (uint8_t*)&remotecid);
			break;





		case L2CAP_CMD_CONNECTION_RESPONSE:






			// interpret result
			switch (hcircvbuf[16])
			{
			case ConnectionSuccessful:

		
				// send configuration request
			
			remotecid=hcircvbuf[12]|(hcircvbuf[13]<<8);
	l2cap_config_request(crd, _l2CapDataIdentifier++, (uint8_t*)&remotecid);

			
				break;
			case ConnectionPending:

				break;
			case ConnectionRefusedPsmNotNupported:

				break;
			case ConnectionRefusedSecurityBlock:

				break;
			case ConnectionRefusedNoResourcesAvailable:

				break;

			default:

				break;
			}
			break;





		case L2CAP_CMD_CONFIG_REQUEST:
		  
		  l2cap_config_response(crd, hcircvbuf[9], (uint8_t*)&remotecid);

		
	
			
			break;




		





		case L2CAP_CMD_CONFIG_RESPONSE:

	if (HID_ControlConnect == true&&HID_InterruptConnect==true)
			{

				hci_sniff_subrating(crd);
				__HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);
				IdleStarted=true;
        
			}
     else if (HID_ControlConnect==true&&HID_InterruptConnect == false && ConnectionMode == Reponse)
			{
				mycid++;
				l2cap_connection_request(crd, _l2CapDataIdentifier++, (uint8_t*)&mycid,
					HID_INTR_PSM);
				 HID_InterruptConnect=true;
			}

	break;



		




		case L2CAP_CMD_DISCONNECT_REQUEST:

			l2cap_disconnection_response(crd, hcircvbuf[9], (uint8_t*)&remotecid, (uint8_t*)&remotecid);
	
        if (HID_ControlConnect == false && ConnectionMode == Reponse)
			{
				mycid++;
				l2cap_connection_request(crd, _l2CapDataIdentifier++, (uint8_t*)&mycid,
					HID_CTRL_PSM);
				 HID_ControlConnect=true;
			}
			
     

			break;




		case L2CAP_CMD_DISCONNECT_RESPONSE:


			break;





		case L2CAP_CMD_ECHO_REQUEST:


			break;




		case L2CAP_CMD_ECHO_RESPONSE:


			break;





		case L2CAP_CMD_INFORMATION_REQUEST:


			break;





		case L2CAP_CMD_INFORMATION_RESPONSE:


			break;


		}

	}
	/* handle (2) acl(2) l2cap(2) cid(2) */
	else if (hcircvbuf[8] == 0xA1 )
	{
		
		rxConut=0;
		// HID report received, parse content and extract gamepad data
		//connection.ParseHidReport(buffer);
		//m_Packet++;
			if (LinkMode==1)
			{
			FuzeUSB();
			}
			if (LinkMode==2)
			{
			NgameUSB();
			}
	}
	else if (hcircvbuf[8] == 0x0b)
	{
		rxConut=0;
		// HID report received, parse content and extract gamepad data
		// connection.ParseHidReport(buffer);
		//m_Packet++;
		 /*
            None = 0,

            XboxData[2],XBOXDATA 
            Up = 1 << 0,
            Down = 1 << 1,
            Left = 1 << 2,
            Right = 1 << 3,
            Start = 1 << 4,
	
            Back = 1 << 5,
            L3 = 1 << 6,
            R3 = 1 << 7,

           
	*/
	
	 uint8_t inpad=*(hcircvbuf+12);
	 uint8_t pads = 0;
	 switch (inpad) {
                         case 1:
                            pads = setbit(pads,1,true);
                        break;
                          case 2:
                             pads = setbit(pads,1,true);
                             pads = setbit(pads,4,true);
                        break;
                          case 3:
                            pads = setbit(pads,4,true);
                        break;
                          case 4:
                              pads = setbit(pads,2,true);
                              pads = setbit(pads,4,true);
                        break;
                          case 5:
                            pads = setbit(pads,2,true);
                        break;
                          case 6:
                              pads = setbit(pads,2,true);
                              pads = setbit(pads,3,true);
                        break;
                          case 7:
                           pads = setbit(pads,3,true);
                        break;
                          case 8:
                          pads = setbit(pads,1,true);
                              pads = setbit(pads,3,true);
                        break;
                    default:
                        break;
                }
	 
	  *(TXData + 2)= pads;
	/*
						LB = 1 << 8([3] byte),
            RB = 1 << 9,
            Guide = 1 << 10,

            A = 1 << 12,
            B = 1 << 13,
            X = 1 << 14,
            Y = 1 << 15
								*/
								uint8_t btons = 0;
                btons = setbit(btons,5,isbittrue(*(hcircvbuf+13),1));
                btons = setbit(btons,6,isbittrue(*(hcircvbuf+13),2));
                btons = setbit(btons,7,isbittrue(*(hcircvbuf+13),3));
                btons = setbit(btons,8,isbittrue(*(hcircvbuf+13),4));
                btons = setbit(btons,1,isbittrue(*(hcircvbuf+13),5));
                btons = setbit(btons,2,isbittrue(*(hcircvbuf+13),6));
                *(TXData + 3)=btons;//??????12??
								/*
                      ([4]byte),
                      L2(???)
                      ([5]byte),
                      R2(???)
                      [6]byte,   left  axis X+
                      [7]byte,   left  axis Y+
											[8]byte left axis X-
											[9]byte left axis Y-
											
											[10]byte,   RIGHT  axis X+
                      [11]byte,   RIGHT  axis Y+
											[12]byte RIGHT axis X-
											[13]byte RIGHT axis Y-
                      
                 */
		 memcpy(TXData + 4, (hcircvbuf) + 8, 1);
		memcpy(TXData + 5, (hcircvbuf) + 10, 1);
		
	             	*(TXData + 6)= *(hcircvbuf+0) -128;//??????12??
                *(TXData + 7)= *(hcircvbuf+1) -128;//??????12??
                *(TXData + 8)= -(*(hcircvbuf+2)-127) ;//??????12??
                *(TXData + 9)= -(*(hcircvbuf+3)-127) ;//??????12??

                //???
                *(TXData + 10)= *(hcircvbuf+4) -128;//??????12??
                *(TXData + 11)= *(hcircvbuf+5) -128;//??????12??
                *(TXData + 12)= -*((hcircvbuf+6)-127) ;//??????12??
                *(TXData + 13)= -(*(hcircvbuf+7)-127) ;//??????12??
		
		
		USBD_CUSTOM_HID_SendReport(hUsbDevice_0, TXData, XINPUT_TX_SIZE);
		//L2CAP_Command(crd,FuzeResponse,7,interrupt_remotecid[0],interrupt_remotecid[1] );
	}
}









/*
struct FrameQueueFormat
{
uint8_t Data[300];

bool bFlagOneFrame;	
};

struct FrameQueueFormat  framequeue[5];

uint8_t queueindex=0;
*/
uint8_t FrameBuf[600];

void USART1_IRQHandler(void)
{
	uint8_t res = 0;
	/* USER CODE BEGIN USART1_IRQn 0 */
	/* USER CODE END USART1_IRQn 0 */
	/* USER CODE BEGIN USART1_IRQn 1 */
if (__HAL_UART_GET_FLAG(&huart1, UART_FLAG_RXNE) != RESET)
	{
		HAL_UART_Receive(&huart1, &res, 1, HAL_MAX_DELAY);

		if (rxConut < RX_BUFFER_SIZE)
		{
			FrameBuf[rxConut] = res;
			rxConut++;
		}
		__HAL_UART_CLEAR_FLAG(&huart1, UART_FLAG_RXNE);
	}
	if (__HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE) != RESET)
	{
		hcircvbuftype=FrameBuf[0];
		memcpy(hcircvbuf,FrameBuf+1,rxConut);
		rxConut=0;
		ACL_event_task();
		__HAL_UART_CLEAR_IDLEFLAG(&huart1);
	}
	/*if (__HAL_UART_GET_FLAG(&huart1, UART_FLAG_RXNE) != RESET)
	{
		HAL_UART_Receive(&huart1, &res, 1, 1000);

		if (rxConut < RX_BUFFER_SIZE)
		{
			framequeue[queueindex].Data[rxConut] = res;
			rxConut++;
		}
		__HAL_UART_CLEAR_FLAG(&huart1, UART_FLAG_RXNE);
	}

	if (__HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE) != RESET)
	{
	
		framequeue[queueindex].bFlagOneFrame = true;

		rxConut = 0;
			for(uint8_t i=0;i<5;i++)
		{
			if(framequeue[i].bFlagOneFrame==false)
			{
		
			queueindex=i;
			HAL_UART_Transmit(&huart2,(uint8_t*)"\rgoto:",6,500);
			sprintf(tmp,"%02x,",queueindex);
			HAL_UART_Transmit(&huart2, (uint8_t*)tmp,3,100);
				if (queueindex==3)
				{
				HAL_UART_Transmit(&huart2,(uint8_t*)"\r03:",3,500);
				}
			break;
			}
		}
	    __HAL_UART_CLEAR_IDLEFLAG(&huart1);



	
	}

*/

}



/*void WaitRX_IT(){
	for(uint8_t i=0;i<5;i++)
	{
		if(framequeue[i].bFlagOneFrame==true)
		{
			
			HAL_UART_Transmit(&huart2,(uint8_t*)"\rprocess:",9,500);
			
			sprintf(tmp,"%02x,",i);
			HAL_UART_Transmit(&huart2, (uint8_t*)tmp,3,100);
			HAL_UART_Transmit(&huart2, (uint8_t*)"\r",1,100);
			for(uint16_t j=0;j<80;j++)
			{
			sprintf(tmp,"%02x,",framequeue[i].Data[j]);
			HAL_UART_Transmit(&huart2, (uint8_t*)tmp,3,100);
			
			}
			
			hcircvbuftype=framequeue[i].Data[0];
			memcpy(hcircvbuf,framequeue[i].Data+1,300);
			
			if (hcircvbuftype==0x04)
			{
				HCI_event_task();
			}
			else if (hcircvbuftype==0x02)
			{
				ACL_event_task();
			}
			else
			{
			
			}
			memset(framequeue[i].Data,0,sizeof(framequeue[i].Data));
			framequeue[i].bFlagOneFrame=false;
			
		}
	}
}
*/




uint16_t CommandLength=0;

/*
void WaitRX()
{
memset(FrameBuf,0,600);
HAL_UART_Receive(&huart1,FrameBuf,600,100);
			if(FrameBuf[0]==0x00){return;}
		HAL_UART_Transmit(&huart2,(uint8_t*)"\rreceive:",9,500);
	
	     for(uint16_t j=0;j<80;j++)
			{
			sprintf(tmp,"%02x,",FrameBuf[j]);
			HAL_UART_Transmit(&huart2, (uint8_t*)tmp,3,100);
			}
		
    
	anotherCommand:	
hcircvbuftype=FrameBuf[CommandIndex];

if(hcircvbuftype==0x04)
{

  CommandLength=	FrameBuf[CommandIndex+2];
  memset(hcircvbuf,0,300);
	
	memcpy(hcircvbuf,FrameBuf+CommandIndex+1,CommandLength+2);	

	HAL_UART_Transmit(&huart2,(uint8_t*)"\rprocess:",9,500);
		sprintf(tmp,"%02x,",hcircvbuftype);
	HAL_UART_Transmit(&huart2, (uint8_t*)tmp,3,100);
	     for(uint16_t j=0;j<80;j++)
			{
			sprintf(tmp,"%02x,",hcircvbuf[j]);
			HAL_UART_Transmit(&huart2, (uint8_t*)tmp,3,100);
			}
			
      HCI_event_task();
      CommandIndex+=CommandLength+3;
		
	
}
		else if(hcircvbuftype==0x02)
		{
			
			CommandLength=	FrameBuf[CommandIndex+3]|(FrameBuf[CommandIndex+4]<<8);
			 memset(hcircvbuf,0,300);
			memcpy(hcircvbuf,FrameBuf+CommandIndex+1,CommandLength+4);	
			HAL_UART_Transmit(&huart2,(uint8_t*)"\rprocess:",9,500);
					sprintf(tmp,"%02x,",hcircvbuftype);
				 HAL_UART_Transmit(&huart2, (uint8_t*)tmp,3,100);
					for(uint16_t j=0;j<80;j++)
					{
					sprintf(tmp,"%02x,",hcircvbuf[j]);
					HAL_UART_Transmit(&huart2, (uint8_t*)tmp,3,100);
					}
			ACL_event_task();
			CommandIndex+=CommandLength+5;
					

		}
	else if (hcircvbuftype==0)
	{
			
	CommandIndex=0;

	}

	hcircvbuftype=FrameBuf[CommandIndex];
		if (hcircvbuftype>0&&CommandIndex>0){
			HAL_UART_Transmit(&huart2,(uint8_t*)"\ranother:",9,500);
			goto anotherCommand; 
			

		}
		CommandIndex=0;
}
*/





void WaitRX_IT2()
{

	HAL_Delay(50);

			if(FrameBuf[0]==0x00){return;}
	
	  	if(FrameBuf[1]==0x00&&FrameBuf[2]==0x00){return;}
	   
			if(rxConut==0){return;}
    
	anotherCommand:	
hcircvbuftype=FrameBuf[CommandIndex];
				#ifdef usart2_log
HAL_UART_Transmit(&huart2,(uint8_t*)"\rprocess:",9,500);
		sprintf(tmp,"%02x,",hcircvbuftype);
		HAL_UART_Transmit(&huart2, (uint8_t*)tmp,3,100);	
			#endif
if(hcircvbuftype==0x04)
{

  CommandLength=	FrameBuf[CommandIndex+2];
  memset(hcircvbuf,0,300);
	
	memcpy(hcircvbuf,FrameBuf+CommandIndex+1,CommandLength+2);	
	#ifdef usart2_log
	
	
	     for(uint16_t j=0;j<CommandLength+2;j++)
			{
			sprintf(tmp,"%02x,",hcircvbuf[j]);
			HAL_UART_Transmit(&huart2, (uint8_t*)tmp,3,100);
			}
			#endif
      HCI_event_task();
      CommandIndex+=CommandLength+3;
		
	
}
		else if(hcircvbuftype==0x02)
		{
			
			CommandLength=	FrameBuf[CommandIndex+3]|(FrameBuf[CommandIndex+4]<<8);
			 memset(hcircvbuf,0,300);
			memcpy(hcircvbuf,FrameBuf+CommandIndex+1,CommandLength+4);	
				#ifdef usart2_log
			
					for(uint16_t j=0;j<CommandLength+2;j++)
					{
					sprintf(tmp,"%02x,",hcircvbuf[j]);
					HAL_UART_Transmit(&huart2, (uint8_t*)tmp,3,100);
					}
					#endif
			ACL_event_task();
			CommandIndex+=CommandLength+5;
					

		}
	else if(hcircvbuftype==0x72)
	{
	
			_l2CapDataIdentifier++;
			l2cap_connection_request(crd, _l2CapDataIdentifier++, (uint8_t*)&mycid,
				HID_CTRL_PSM);
			HID_ControlConnect=true;
			rxConut=0;
  CommandIndex=0;		
	memset(FrameBuf,0,600);
		HCI_SendQueue();
	}
		else 
	{
			HAL_UART_Transmit(&huart2, (uint8_t*)"comidex",6,100);
		sprintf(tmp,"%02x,",CommandIndex);
			HAL_UART_Transmit(&huart2, (uint8_t*)tmp,3,100);
			HAL_UART_Transmit(&huart2, (uint8_t*)"rxqty",5,100);
		sprintf(tmp,"%02x,",rxConut);
			HAL_UART_Transmit(&huart2, (uint8_t*)tmp,3,100);
		
		  for(uint16_t j=CommandIndex;j<rxConut;j++)
			{
			sprintf(tmp,"%02x,",hcircvbuf[j]);
			HAL_UART_Transmit(&huart2, (uint8_t*)tmp,3,100);
			}
	rxConut=0;
  CommandIndex=0;		
	memset(FrameBuf,0,600);
		HCI_SendQueue();
	return;

	}

	hcircvbuftype=FrameBuf[CommandIndex];
		if (hcircvbuftype>0&&CommandIndex>0&&IdleStarted==false&&CommandIndex<rxConut){
				#ifdef usart2_log
			HAL_UART_Transmit(&huart2,(uint8_t*)"\ranother:",9,500);
			#endif
			goto anotherCommand; 
			

		}
	
		CommandIndex=0;
//			HAL_UART_Transmit(&huart2,(uint8_t*)"\rhavedo:",8,500);
//     for(uint16_t j=0;j<rxConut;j++)
//			{
//			sprintf(tmp,"%02x,",FrameBuf[j]);
//			HAL_UART_Transmit(&huart2, (uint8_t*)tmp,3,100);
//			}
		HCI_SendQueue();
		rxConut=0;
		memset(FrameBuf,0,600);
}




/*
uint8 t txData[]="Hello World!\r\n";
HAL UART Transmit(&huart1,txData, sizeof(txData)-1, HAL MAX DELAY),
uint8 t rxData[10];
HAL UART Receive(&huart1, rxData, 10, HAL MAX DELAY);
*/


/* USER CODE END 0 */

int main(void)
{


	/* USER CODE BEGIN 1 */

	/* USER CODE END 1 */

	/* MCU Configuration----------------------------------------------------------*/

	/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
	HAL_Init();

	/* Configure the system clock */
	SystemClock_Config();

	/* Initialize all configured peripherals */
	MX_GPIO_Init();
	//MX_DMA_Init();
	//MX_ADC1_Init();
	MX_USB_DEVICE_Init();
	//  MX_TIM2_Init();
		/*USART */
	MX_USART1_Init();

 


	/* USER CODE BEGIN 2 */


  //	HAL_DMA_Init(&hdma_adc1); 
  //	HAL_ADC_Start_DMA( &hadc1, ADC_buffer, 6 );
  //	HAL_ADC_Start_IT( &hadc1 );

	  // Declare port and pins
  //	declareButtonPins();
  //	declareAnalogPins();
  //	declareEncoderPins();
	
//	    crd=&rd_list[0];
//	  crd->disc_bdaddr[0]=0x14;
//	  crd->disc_bdaddr[1]=0x2f;
//	  crd->disc_bdaddr[2]=0x00;
//		crd->disc_bdaddr[3]=0x12;
//		crd->disc_bdaddr[4]=0xff;
//		crd->disc_bdaddr[5]=0x4c;
//			 
//	  	crd->disc_linkkey[0]=0x0e;
//			crd->disc_linkkey[1]=0x77;
//			crd->disc_linkkey[2]=0x86;
//			crd->disc_linkkey[3]=0xfd;
//			crd->disc_linkkey[4]=0x4c;
//			crd->disc_linkkey[5]=0x3f;
//			crd->disc_linkkey[6]=0x7c;
//			crd->disc_linkkey[7]=0xf6;
//			crd->disc_linkkey[8]=0xd4;
//			crd->disc_linkkey[9]=0x4c;
//			crd->disc_linkkey[10]=0x82;
//			crd->disc_linkkey[11]=0xe6;
//			crd->disc_linkkey[12]=0x98;
//			crd->disc_linkkey[13]=0x60;
//			crd->disc_linkkey[14]=0x3b;
//			crd->disc_linkkey[15]=0x1d;
//			
//			crd->remote_name[0]='f';
//			crd->remote_name[1]='u';
//			crd->remote_name[2]='z';
//			crd->remote_name[3]='e';
//			
//	Rdlist2flash();
	
	
	Flash2Rdlist();
	
  HAL_Delay(5000);
	hci_reset();
	ConnectionMode = Reponse;
  HCI_SendQueue();
  bool connecbd=false;
  /* Get tick */ 
 
 while (IdleStarted==false)
 {
 	WaitRX_IT2();
	 //WaitRX_IT();
	if(scanrun==true&&tickstart==0)
	{
	 tickstart = HAL_GetTick();
		
	}
  if(scanrun==true&&tickstart!=0&&HAL_GetTick()-tickstart>5000)
	{
		  
			for(uint8_t i=0;i<5;i++)
				{
						if (rd_list[i].state!=0x0)
						{
							connecbd=true;
						break;
						}
				}
				if (connecbd==false)
			{
			hci_inquiry();
			HCI_SendQueue();
			}
     scanrun=false;
	}		
	 
 }
	while(true)
	{
	HAL_Delay(50);
	}

	/* USER CODE END 2 */


	/* USER CODE END 3 */

}




/** System Clock Configuration
*/
void SystemClock_Config(void)
{

	RCC_OscInitTypeDef RCC_OscInitStruct;
	RCC_ClkInitTypeDef RCC_ClkInitStruct;
	RCC_PeriphCLKInitTypeDef PeriphClkInit;

	RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
	RCC_OscInitStruct.HSEState = RCC_HSE_ON;
	RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
	RCC_OscInitStruct.HSIState = RCC_HSI_ON;
	RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
	RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
	RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
	HAL_RCC_OscConfig(&RCC_OscInitStruct);

	RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK
		| RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
	RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
	RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
	RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
	RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
	HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2);

	PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC | RCC_PERIPHCLK_USB;
	PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV6;
	PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_PLL_DIV1_5;
	HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit);

	HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq() / 1000);

	HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);

	/* SysTick_IRQn interrupt configuration */
	HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
}

/* ADC1 init function */
void MX_ADC1_Init(void)
{




	//	ADC_ChannelConfTypeDef sConfig;

	//	/**Common config
	//	*/
	//	hadc1.Instance = ADC1;
	//	hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE;
	//	hadc1.Init.ContinuousConvMode = ENABLE;
	//	hadc1.Init.DiscontinuousConvMode = DISABLE;
	//	hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
	//	hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
	//	hadc1.Init.NbrOfConversion = 6;
	//	HAL_ADC_Init(&hadc1);

	//	/**Configure Regular Channel
	//	*/
	//	sConfig.Channel = ADC_CHANNEL_0;
	//	sConfig.Rank = 1;
	//	sConfig.SamplingTime = ADC_SAMPLETIME_13CYCLES_5;
	//	HAL_ADC_ConfigChannel(&hadc1, &sConfig);

	//	/**Configure Regular Channel
	//	*/
	//	sConfig.Channel = ADC_CHANNEL_1;
	//	sConfig.Rank = 2;
	//	HAL_ADC_ConfigChannel(&hadc1, &sConfig);

	//	/**Configure Regular Channel
	//	*/
	//	sConfig.Channel = ADC_CHANNEL_2;
	//	sConfig.Rank = 3;
	//	HAL_ADC_ConfigChannel(&hadc1, &sConfig);

	//	/**Configure Regular Channel
	//	*/
	//	sConfig.Channel = ADC_CHANNEL_3;
	//	sConfig.Rank = 4;
	//	HAL_ADC_ConfigChannel(&hadc1, &sConfig);

	//	/**Configure Regular Channel
	//	*/
	//	sConfig.Channel = ADC_CHANNEL_4;
	//	sConfig.Rank = 5;
	//	HAL_ADC_ConfigChannel(&hadc1, &sConfig);

	//	/**Configure Regular Channel
	//  */
	//	sConfig.Channel = ADC_CHANNEL_5;
	//	sConfig.Rank = 6;
	//	HAL_ADC_ConfigChannel(&hadc1, &sConfig);

}


/**
  * Enable DMA controller clock
  */
void MX_DMA_Init(void)
{
	/* DMA controller clock enable */
	__HAL_RCC_DMA1_CLK_ENABLE();

	/* DMA interrupt init */


	/* DMA1_Channel1_IRQn interrupt configuration */
	HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 0, 0);
	HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);

}


/** Configure pins as
		* Analog
		* Input
		* Output
		* EVENT_OUT
		* EXTI
*/
void MX_GPIO_Init(void)
{

	GPIO_InitTypeDef GPIO_InitStruct;

	/* GPIO Ports Clock Enable */
	__HAL_RCC_GPIOC_CLK_ENABLE();
	__HAL_RCC_GPIOD_CLK_ENABLE();
	__HAL_RCC_GPIOA_CLK_ENABLE();
	__HAL_RCC_GPIOB_CLK_ENABLE();


	/*Configure GPIO pin Output Level */
	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15, GPIO_PIN_RESET);

	/*Configure GPIO pin Output Level */
  //  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_9, GPIO_PIN_RESET);
  //  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_RESET);
	/*Configure GPIO pins : PC13 PC14 PC15 */
	GPIO_InitStruct.Pin = GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15;
	GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
	HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

	//	/*Configure GPIO pins : PB10 PB11 PB12 PB13
	//							 PB14 PB15 PB3 PB4
	//							 PB5 PB6 PB7 */
	//							 //B10,B11 touart
	//	GPIO_InitStruct.Pin = //GPIO_PIN_10 | GPIO_PIN_11 | 
	//	GPIO_PIN_12 | GPIO_PIN_13
	//		| GPIO_PIN_14 | GPIO_PIN_15 | GPIO_PIN_3 | GPIO_PIN_4
	//		| GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7;
	//	GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
	//	GPIO_InitStruct.Pull = GPIO_PULLUP;
	//	HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

	//	/*Configure GPIO pins : PA8 PA9 PA10 PA15 */
	//	//GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_15;
	//	GPIO_InitStruct.Pin = GPIO_PIN_8 | GPIO_PIN_15;
	//	GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
	//	GPIO_InitStruct.Pull = GPIO_PULLUP;
	//	HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);


		/*pa9 pa10 set to usart*/

		//B8 OUTPUUT

		  /*Configure GPIO pin : PB8 */

	//	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_RESET);

	//	GPIO_InitStruct.Pin = GPIO_PIN_8;
	//	//  GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
	//	//  GPIO_InitStruct.Pull = GPIO_PULLUP;
	//	GPIO_InitStruct.Pull = GPIO_NOPULL;
	//	GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
	//	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
	//	HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);



		//  /*Configure GPIO pin : PB9 */
		//  GPIO_InitStruct.Pin = GPIO_PIN_9;
		//  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
		//  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
		//  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

		//  /* EXTI interrupt init*/
		//  HAL_NVIC_SetPriority(EXTI9_5_IRQn, 0, 0);
		//  HAL_NVIC_EnableIRQ(EXTI9_5_IRQn);

}

/* USER CODE BEGIN 4 */

/**	Encoder ISR
*		Handles the encoder that control the steering wheel position
**/
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) {
	/* Handls encoder of the x360 racing wheel
	if( GPIO_Pin ==  encoderPins[0].pin ){
		if( HAL_GPIO_ReadPin( encoderPins[1].port, encoderPins[1].pin ) == SET ){
			wheelEncoderValue++;
		}else{
			wheelEncoderValue--;
		}
	}
	*/
}

/**	ADC ISR
*		Handles the values from ADC after the conversion finished
*/
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) {

	if (adcValueReady == 0) {

		leftTriggerValue_ADC = ADC_buffer[0];
		rightTriggerValue_ADC = ADC_buffer[1];
		xRightStickValue_ADC = ADC_buffer[2];
		yRightStickValue_ADC = ADC_buffer[3];
		xLeftStickValue_ADC = ADC_buffer[4];
		yLeftStickValue_ADC = ADC_buffer[5];

		adcValueReady = 1;
	}

}

/* USER CODE END 4 */

#ifdef USE_FULL_ASSERT

/**
   * @brief Reports the name of the source file and the source line number
   * where the assert_param error has occurred.
   * @param file: pointer to the source file name
   * @param line: assert_param error line source number
   * @retval None
   */
void assert_failed(uint8_t* file, uint32_t line)
{
	/* USER CODE BEGIN 6 */
	/* User can add his own implementation to report the file name and line number,
	  ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
	  /* USER CODE END 6 */

	}

#endif

/**
  * @}
  */

  /**
	* @}
  */

  /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
